package com.lcc.lynx.base.system.controller;

import com.fasterxml.jackson.databind.JavaType;
import com.github.pagehelper.PageInfo;
import com.lcc.lynx.base.system.pojo.dv.SysCacheDV;
import com.lcc.lynx.common.ResultVO;
import com.lcc.lynx.security.annotation.Permission;
import com.lcc.lynx.common.cache.service.CacheService;
import com.lcc.lynx.common.utils.JsonUtil;
import com.lcc.lynx.common.utils.StrUtil;
import com.lcc.lynx.jdbc.pojo.PageParams;

import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 缓存管理控制实现
 * @auth lcc
 * @date 2025-01-15
 */
@RestController
@AllArgsConstructor
@RequestMapping("/sys/cache")
public class SysCacheController{

    private CacheService cacheService;

    @Permission(Permission.search)
    @RequestMapping("/get")
    public ResultVO get(SysCacheDV dv){
        if(StrUtil.isEmpty(dv.getKey())){
            return ResultVO.fail("key不能为空");
        }
        Object o = cacheService.get(dv.getKey());
        String value;
        String className = null;
        if(o instanceof Number){
            value = o.toString();
            className = o.getClass().getName();
        } else if(o instanceof String){
            value = String.format("\"%s\"", o);
            className = o.getClass().getName();
        } else if(o instanceof List){
            List<Object> list = (List<Object>) o;
            value = JsonUtil.toJSONString(o);
            if(list.size() > 0){
                className = list.get(0).getClass().getName();
            }
        } else{
            value = JsonUtil.toJSONString(o);
            className = o.getClass().getName();
        }
        dv.setValue(value);
        dv.setClassName(className);
        return ResultVO.success(dv);
    }

    @Permission(Permission.upd)
    @RequestMapping("/update")
    public ResultVO<String> update(SysCacheDV dv){
        if(StrUtil.isEmpty(dv.getKey())){
            return ResultVO.fail("key不能为空");
        }
        if(StrUtil.isEmpty(dv.getValue())){
            return ResultVO.fail("value不能为空");
        }
        Object o;
        String value = dv.getValue();
        if(String.class.getName().equals(dv.getClassName())){
            if(value.startsWith("\"") && value.endsWith("\"")){
                o = value.substring(1, value.length() - 1);
            }else{
                o = value;
            }
        }else if(value.startsWith("[")){
            try {
                JavaType javaType = JsonUtil.getCollectionType(ArrayList.class, Class.forName(dv.getClassName()));
                o = JsonUtil.parseObject(value, javaType);
            } catch (ClassNotFoundException e) {
                return ResultVO.fail("className错误：" + dv.getClassName());
            } catch (IOException e) {
                return ResultVO.fail("value格式错误：" + e.getMessage());
            }
        }else if(value.startsWith("{")){
            try {
                o = JsonUtil.parseObject(value, Class.forName(dv.getClassName()));
            } catch (ClassNotFoundException e) {
                return ResultVO.fail("className错误：" + dv.getClassName());
            } catch (IOException e) {
                return ResultVO.fail("value格式错误：" + e.getMessage());
            }
        }else { // number
            if(StrUtil.isNumeric(value)){
                if(value.contains(".")){
                    o = Double.parseDouble(value);
                }else{
                    o = Long.parseLong(value);
                }
            }else{
                return ResultVO.fail("只能是数字类型");
            }
        }

        cacheService.set(dv.getKey(), o, 7, TimeUnit.DAYS);

        return ResultVO.success();
    }


    /**
     * 分页查询
     * @param dto
     * @param pageParams
     * @return
     */
    @Permission(Permission.search)
    @RequestMapping("/page")
    public ResultVO<PageInfo<SysCacheDV>> page(SysCacheDV dto, PageParams pageParams){
        String key = "*";
        if(StrUtil.isNotEmpty(dto.getGroup()) && StrUtil.isNotEmpty(dto.getKey())){
            key = String.format("%s:*%s*",dto.getGroup(), dto.getKey());
        }else if(StrUtil.isNotEmpty(dto.getGroup()) && StrUtil.isEmpty(dto.getKey())){
            key = String.format("%s:*",dto.getGroup());
        }else if(StrUtil.isEmpty(dto.getGroup()) && StrUtil.isNotEmpty(dto.getKey())){
            key = String.format("*%s*", dto.getKey());
        }
        PageInfo<SysCacheDV> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageNum(1);
        pageInfo.setPageSize(pageParams.getPageSize());
        List<String> strings = cacheService.searchKey(key);
        if(strings == null || strings.size() == 0){
            return ResultVO.success(pageInfo);
        }
        List<SysCacheDV> list = new ArrayList<>();
        pageInfo.setList(list);
        pageInfo.setTotal(strings.size());
        pageInfo.setPageNum(pageParams.getPageNum());
        int i = pageParams.getPageSize() * (pageParams.getPageNum() - 1);
        for (; i < strings.size(); i++) {
            if(i >= pageParams.getPageSize() * pageParams.getPageNum()){
                break;
            }
            SysCacheDV sysCacheDV = new SysCacheDV();
            sysCacheDV.setKey(strings.get(i));
            list.add(sysCacheDV);
        }
        return ResultVO.success(pageInfo);
    }

    @Permission(Permission.del)
    @RequestMapping("/delete")
    public ResultVO delete(@RequestParam(required = false, name = "idList") String idList){
        if(StrUtil.isEmpty(idList)){
            return ResultVO.fail("idList不能为空");
        }
        List<String> list = Arrays.asList(idList.split(","));
        cacheService.del(list);
        return ResultVO.success();
    }



}